"""
console 2048

@author: tpig
@date: 2020/12/7
"""
import random
import os

data = [[0 for i in range(4)] for j in range(4)]


def print_board():
    for line in data:
        print("|", end="")
        for cell in line:
            print(f"{cell:4} |", end="")
        print("\n", "-" * 23)


def check_full():
    """check is the board is fulled"""
    for line in data:
        for cell in line:
            if cell == 0:
                return False
    return True


def find_blank():
    if check_full():
        return None
    line = random.randint(0, 3)
    col = random.randint(0, 3)
    while data[line][col] != 0:
        line = random.randint(0, 3)
        col = random.randint(0, 3)
    return line, col


def init_board():
    line, col = find_blank()

    data[line][col] = 2  # random.choice([2, 4])
    line, col = find_blank()
    data[line][col] = 2  # random.choice([2, 4])


def clear_screen():
    os.system("cls")


#################################
def move_box_up(src, col):
    if data[src][col] == 0:
        return

    if src == 0:
        return
    else:
        if data[src-1][col] == 0:
            data[src-1][col] = data[src][col]
            data[src][col] = 0
            move_box_up(src-1, col)
        else:
            if data[src-1][col] == data[src][col]:
                data[src-1][col] = data[src][col] * 2
                data[src][col] = 0


def move_box_down(src, col):
    if data[src][col] == 0:
        return

    if src == 3:
        return
    else:
        if data[src + 1][col] == 0:
            data[src + 1][col] = data[src][col]
            data[src][col] = 0
            move_box_down(src + 1, col)
        else:
            if data[src + 1][col] == data[src][col]:
                data[src + 1][col] = data[src][col] * 2
                data[src][col] = 0


def move_box_left(src, line):
    if data[line][src] == 0:
        return

    if src == 0:
        return
    else:
        if data[line][src-1] == 0:
            data[line][src-1] = data[line][src]
            data[line][src] = 0
            move_box_left(src-1, line)
        else:
            if data[line][src-1] == data[line][src]:
                data[line][src-1] = data[line][src] * 2
                data[line][src] = 0


def move_box_right(src, line):
    if data[line][src] == 0:
        return

    if src == 3:
        return
    else:
        if data[line][src + 1] == 0:
            data[line][src + 1] = data[line][src]
            data[line][src] = 0
            move_box_right(src + 1, line)
        else:
            if data[line][src + 1] == data[line][src]:
                data[line][src + 1] = data[line][src] * 2
                data[line][src] = 0


#################################
def stack_up(col):
    move_box_up(1, col)
    move_box_up(2, col)
    move_box_up(3, col)

def stack_down(col):
    move_box_down(2, col)
    move_box_down(1, col)
    move_box_down(0, col)

def stack_left(line):
    move_box_left(1, line)
    move_box_left(2, line)
    move_box_left(3, line)

def stack_right(line):
    move_box_right(2, line)
    move_box_right(1, line)
    move_box_right(0, line)

####################################
def move_left():
    for line in range(4):
        stack_left(line)

def move_right():
    for line in range(4):
        stack_right(line)

def move_down():
    for col in range(4):
        stack_down(col)

def move_up():
    for col in range(4):
        stack_up(col)


def insert_new_num():
    line, col = find_blank()
    data[line][col] = 2

def main():
    command = ""
    init_board()
    while not command == "q":
        clear_screen()
        print_board()

        # check the if the board  is full
        if check_full():
            break

        command = input(">")
        if command.lower() == "a":
            move_left()
        if command.lower() == "s":
            move_down()
        if command.lower() == "d":
            move_right()
        if command.lower() == "w":
            move_up()

        # insert a new number
        insert_new_num()
        
    print("GAME OVER")

if __name__ == "__main__":
    main()